package com.blog.aop;

import com.blog.mapper.PvLogMapper;
import com.blog.model.PvLog;
import com.blog.util.HttpUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Date;

/**
 * @Description: pv日志统计
 * @Author: 刘会俊
 * @Date: 2018-12-20 11:35
 */
@Component
@Aspect
public class PvAopLog {


    @Autowired
    private PvLogMapper pvLogMapper;

    private final static Logger LOGGER = LoggerFactory.getLogger(PvAopLog.class);

    @Pointcut(value = "execution(public * com.blog.controller..*.*(..))")
    public void pointCut(){

    }

    @Pointcut(value = "@annotation(com.blog.aop.MethodTime)")
    public void methodTImePointCut(){

    }

    /**
     *@description: 访问接口以后对接口做统计
     *@author: 刘会俊
     *@params: [joinPoint]
     *@return: void
     */
    @After(value = "pointCut())")
    public void after(JoinPoint joinPoint){
        PvLog pvLog = new PvLog();
        LOGGER.info("当前请求的方法名:{}",joinPoint.getSignature().getName());
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        PvCount pvCount = ((MethodSignature) joinPoint.getSignature()).getMethod().getDeclaredAnnotation(PvCount.class);
        pvLog.setType(pvCount == null ? "默认" : pvCount.description().getPosition());
        String realIp = HttpUtil.getIpAddr(request);
        LOGGER.info("当前请求来源IP地址为:{}",realIp);
        pvLog.setUpdateTime(new Date());
        pvLog.setReferer(request.getHeader("Referer"));
        pvLog.setVisitTime(1);
        pvLog.setIp(realIp);
        //pvLogMapper.insert(pvLog);
        LOGGER.info("主键:{}",pvLog.getId());
    }


    /**
     *@description: 统计方法时长
     *@author: 刘会俊
     *@params: [proceedingJoinPoint]
     *@return: java.lang.Object
     */
    @Around(value = "methodTImePointCut()")
    public Object methodTimePointCutAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object object;
        Class clazz = proceedingJoinPoint.getTarget().getClass();
        MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
        object = proceedingJoinPoint.proceed();
        if(clazz.isAnnotationPresent(MethodTime.class) || methodSignature.getMethod().isAnnotationPresent(MethodTime.class)){
            LOGGER.info("当前线程<{}>执行{}方法耗时{}毫秒",Thread.currentThread().getId(),methodSignature.getName(),System.currentTimeMillis()-startTime);
        }
        boolean requestMappinPresent = methodSignature.getMethod().isAnnotationPresent(GetMapping.class);
        if(requestMappinPresent){
            RequestMapping requestMapping = methodSignature.getMethod().getAnnotation(RequestMapping.class);
            LOGGER.info("[获得路径]{}", Arrays.asList(requestMapping.path()));
        }
        return object;
    }

}
